/**
 * Copyright (c) 2015-2016, Michael Yang 杨福海 (fuhai999@gmail.com).
 *
 * Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.gnu.org/licenses/lgpl-3.0.txt
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.jpress.utils;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;
import com.jfinal.kit.PathKit;
import com.jfinal.log.Log;
import com.jfinal.upload.UploadFile;
import io.jpress.model.query.OptionQuery;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import me.duzhi.ilog.cms.function.SFTPKit;
import sun.net.ftp.FtpClient;

public class AttachmentUtils {

  public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");

  /**
   * @return new file relative path
   */
  public static String moveFile(UploadFile uploadFile) {
    if (uploadFile == null) {
      return null;
    }

    File file = uploadFile.getFile();
    if (!file.exists()) {
      return null;
    }

    String webRoot = PathKit.getWebRootPath();
    String uuid = UUID.randomUUID().toString().replace("-", "");
    String upload_real_path = OptionQuery.me().findValue("upload_real_path");
    StringBuilder newFileName = new StringBuilder(webRoot).append(File.separator)
        .append(upload_real_path != null ? upload_real_path : "attachment")
        .append(File.separator).append(dateFormat.format(new Date())).append(File.separator)
        .append(uuid)
        .append(FileUtils.getSuffix(file.getName()));
    File newfile = new File(newFileName.toString());
    if (!newfile.getParentFile().exists()) {
      newfile.getParentFile().mkdirs();
    }
    file.renameTo(newfile);
    if (Ftp.isEnabled()) {
      Ftp.sftpFile(dateFormat.format(new Date()), newfile);
    }

    return FileUtils.removePrefix(newfile.getAbsolutePath(), webRoot);

  }

  public static boolean ftpUpload(String dir, File file) {
    return Ftp.sftpFile(dir, file);
  }

  static List<String> imageSuffix = new ArrayList<String>();

  static {
    imageSuffix.add(".jpg");
    imageSuffix.add(".jpeg");
    imageSuffix.add(".png");
    imageSuffix.add(".bmp");
    imageSuffix.add(".gif");
  }

  public static boolean isImage(String path) {
    String sufffix = FileUtils.getSuffix(path);
    if (StringUtils.isNotBlank(sufffix)) {
      return imageSuffix.contains(sufffix.toLowerCase());
    }
    return false;
  }

  public static final Log log = Log.getLog(AttachmentUtils.class);

  static class Ftp {

    public static final String SFTP_REQ_ENABLE = "sftp.enable";

    public static boolean isEnabled() {
      Boolean enable = OptionQuery.me().findValueAsBool(SFTP_REQ_ENABLE);
      enable = enable == null ? false : enable;
      if (!enable) {
        if (log.isDebugEnabled()) {
          log.debug("do not use Sftp mode,so don't put file to SFTP Server ");
        }
      }
      return enable;
    }


    public static boolean sftpFile(String dir, File file) {
      boolean enable = Boolean.valueOf(OptionQuery.me().findValue(SFTP_REQ_ENABLE));
      if (!enable) {
        if (log.isDebugEnabled()) {
          log.debug("do not use Sftp mode,so don't put file to SFTP Server ");
        }
        return true;
      }
      if (log.isDebugEnabled()) {
        log.debug("use ftp mode ");
      }
      if (
          !(checkDefine(SFTPKit.SFTP_REQ_HOST, true) &&
              checkDefine(SFTPKit.SFTP_REQ_USERNAME, true) &&
              checkDefine(SFTPKit.SFTP_REQ_PASSWORD, true) &&
              checkDefine(SFTPKit.SFTP_REQ_PORT, true))) {
        if (log.isDebugEnabled()) {
          log.debug("must define message not defined");
        }
        return false;
      }
      SFTPKit sftpKit = new SFTPKit();
      try {
        Map map = new HashMap<>();
        map.put(SFTPKit.SFTP_REQ_HOST, OptionQuery.me().findValue(SFTPKit.SFTP_REQ_HOST));
        map.put(SFTPKit.SFTP_REQ_USERNAME, OptionQuery.me().findValue(SFTPKit.SFTP_REQ_USERNAME));
        map.put(SFTPKit.SFTP_REQ_PASSWORD, OptionQuery.me().findValue(SFTPKit.SFTP_REQ_PASSWORD));
        map.put(SFTPKit.SFTP_REQ_PORT, OptionQuery.me().findValue(SFTPKit.SFTP_REQ_PORT));
        ChannelSftp sftp = sftpKit.getChannel(map, 2000);
        try {
          sftp.ls(dir);
        } catch (Exception e) {
          sftp.mkdir(dir);
        }
        sftp.cd(dir);
        sftp.put(new FileInputStream(file), file.getName());
      } catch (JSchException e) {

        if (log.isErrorEnabled()) {
          log.error("登录出错", e);
        }
        return false;
      } catch (SftpException e) {
        if (log.isErrorEnabled()) {
          log.error("上传出错", e);
        }

        return false;
      } catch (FileNotFoundException e) {
        if (log.isErrorEnabled()) {
          log.error("没有这个文件", e);
        }
        return false;
      } finally {
        try {
          sftpKit.closeChannel();
        } catch (Exception e) {
        }
      }
      return true;
    }

    private static boolean checkDefine(String key, boolean isMust) {
      String value = OptionQuery.me().findValue(key);
      if (isMust) {
        if (StringUtils.isBlank(value)) {
          return false;
        }
      }
      if (log.isDebugEnabled()) {
        log.debug("define key:" + key + ",define value is:" + value);
      }
      return true;
    }
  }


  public static void main(String[] args) {
    System.out.println(FileUtils.getSuffix("xxx.jpg"));
  }

}
